package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.domain.Destination;
import cn.wolfcode.luowowo.domain.Strategy;
import cn.wolfcode.luowowo.domain.Travel;
import cn.wolfcode.luowowo.domain.UserInfo;
import cn.wolfcode.luowowo.query.TravelCondition;
import cn.wolfcode.luowowo.query.TravelQuery;
import cn.wolfcode.luowowo.repository.TravelRepository;
import cn.wolfcode.luowowo.service.IDestinationService;
import cn.wolfcode.luowowo.service.ITravelService;
import cn.wolfcode.luowowo.util.DBHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class TravelServiceImpl implements ITravelService {


    @Autowired
    private TravelRepository travelRepository;


    @Autowired
    private MongoTemplate mongoTemplate;


    @Autowired
    private UserInfoServiceImpl userInfoService;


    @Autowired
    private DestinationServiceImpl destinationService;


    @Override
    public void save(Travel travel) {
//        travel.setId(null);
        if (StringUtils.hasLength(travel.getDestId())){
            // 通过当前游记的目的地Id找目的地
            Destination destination = destinationService.get(travel.getDestId());
            // 目的地名字set 回去
            travel.setDestName(destination.getName());
            // 发布时间
            travel.setCreateTime(new Date());
        }
        // 最后更新时间
        travel.setLastUpdateTime(new Date());
        travelRepository.save(travel);
    }

    @Override
    public void update(Travel travel) {

        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(travel.getId()));
        if (StringUtils.hasLength(travel.getDestId())){
            // 通过当前游记的目的地Id找目的地
            Destination destination = destinationService.get(travel.getDestId());
            // 目的地名字set 回去
            travel.setDestName(destination.getName());

        }
        // 最后更新时间
        travel.setLastUpdateTime(new Date());

        // 需要更新的字段
        DBHelper.update(mongoTemplate,query,travel,"state","title","coverUrl",
                                                             "travelTime","person","isPublic",
                                                              "day","perExpend","destId","summary",
                                                              "content","destName","lastUpdateTime");


//        travelRepository.save(travel);
    }

    @Override
    public void delete(String id) {
        travelRepository.deleteById(id);

    }

    @Override
    public Travel get(String id) {
        Optional<Travel> op = travelRepository.findById(id);
        if (op.isPresent()){
            Travel travel = op.get();
            // 通过拿到游记对象的userId  找到当前登陆对象
            UserInfo userInfo = userInfoService.get(travel.getUserId());
            // set 回当前游记对象的Author 属性中
            travel.setAuthor(userInfo);
            // 通过拿到游记对象的DestId  找到当前目的地对象
            Destination destination = destinationService.get(travel.getDestId());
            // set 回当前游记对象的Dest 属性中
            travel.setDest(destination);
            return travel;
        }
        return null;
    }

    @Override
    public List<Travel> list()
    {
        return travelRepository.findAll();
    }

    // 分页操作
    @Override
    public Page<Travel> query(TravelQuery qo) {

        Query query = new Query();
        // 查询总页数
        long count = mongoTemplate.count(query, Travel.class);
        if (count == 0){
            return Page.empty();
        }

        //  给排序条件一个默认值
        String order = "_id";
        // 当传上来的OrderType  为 1时
        if (qo.getOrderType() == TravelQuery.Hot_type){
            // 排序条件设置为人气排序
            order = "viewnum";
        }else if (qo.getOrderType() == TravelQuery.New_type){
            // 按最新发布时间排序
            order = "createTime";
        }


        // 目的地条件
        if (StringUtils.hasLength(qo.getDestId())){
            query.addCriteria(Criteria.where("destId").is(qo.getDestId()));
        }

        // 出行天数条件查询
        TravelCondition day = qo.getDay();
        if (day != null){
            query.addCriteria(Criteria.where("day").gte(day.getMin()).lte(day.getMax()));
        }

        // 花费金额条件查询
        TravelCondition perExpend = qo.getPerExpend();
        if (perExpend != null){
            query.addCriteria(Criteria.where("perExpend").gte(perExpend.getMin()).lte(perExpend.getMax()));
        }


        // 分页排序
        Pageable pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.DESC, order);

        // 查询总条件
        query.with(pageable);

        // 拿到所有对象的集合
        List<Travel> list = mongoTemplate.find(query, Travel.class);

        // 遍历游记对象.用userInfoService get的方法 拿到发布对象 set 回游记对象的Author 属性中
        for (Travel travel : list) {
            travel.setAuthor(userInfoService.get(travel.getUserId()));
        }

        return new PageImpl<>(list,pageable,count);

    }

    /**
     * 通过id 修改游记状态
     * @param id
     * @param state
     */
    @Override
    public void changeState(String id, Integer state) {

        // 通过传上来的id 拿到 对应的游记对象
        Travel travel = this.get(id);
        // 当对象不为空,且状态为待发布或已经发布时才进入
        if (travel != null && (travel.getState() == Travel.STATE_WAITING || travel.getState() == Travel.STATE_RELEASE )){
            // 如果传上来的状态为发布
            if (state == Travel.STATE_RELEASE){
                // 把对象的属性设置为
                travel.setState(Travel.STATE_RELEASE);
                // 把发布时间设为当前时间
                travel.setReleaseTime(new Date());
                // 把修改时间设置为当前时间
                travel.setCreateTime(new Date());
                // 如果传上来的状态为拒绝或者下架
            }else if (state == Travel.STATE_REJECT){
                travel.setState(Travel.STATE_REJECT);
                // 把最后修改修改时间设置为当前时间
                travel.setLastUpdateTime(new Date());

            }

        }
        // 修改回去
        this.update(travel);

    }

    /**
     * 只拿点击量前三的游记
     * @param destId
     * @return
     */
    @Override
    public List<Travel> queryViewNumTop3(String destId) {
        // 只拿点击量前三的游记
        Pageable pageable = PageRequest.of(0,3,Sort.Direction.DESC,"Viewnum");

        //  通过目的地Id在攻略明细中找
        List<Travel> travels = travelRepository.findByDestId(destId,pageable);
        return travels;
    }

    /**
     * 通过目的地名字找当前目的地下的所有游记集合
     * 记得需要找到作者  set 回Author 属性中
     * @param name
     * @return
     */
    @Override
    public List<Travel> findByDestName(String name) {

        List<Travel> travels = travelRepository.findByDestName(name);
        for (Travel travel : travels) {
            travel.setAuthor(userInfoService.get(travel.getUserId()));
        }
        return travels;
    }


}
